﻿#include <iostream>
#include <algorithm>
#include <memory.h>

using namespace std;
/*
http://oj.daimayuan.top/course/14/problem/684

给你一张 n个顶点 m条边的有向简单图，顶点编号从 1到 n
，每条边都有一个边权，边权为非负整数。

现在有 k组询问，每组询问读入两个整数 x,y
，请求出从 x号点到 y号点的最短路的长度。如果不存在从 x号点到 y号点的路径，请输出 -1。

输入格式
第一行三个整数 n,m,k，表示图的顶点数、边数和询问次数。

接下来 m行，每行三个整数 x,y,z，表示 x号点到 y号点有一条边权为 z的有向边。

接下来 k行，每行两个整数 x,y，表示一组询问。

输出格式
输出共 k行，每行一个数表示一组询问的答案。

样例输入
3 3 2
1 2 3
2 3 2
3 2 1
1 3
3 1
样例输出
5
-1
数据规模
对于所有数据，保证 2≤n≤300,0≤m≤20000,1≤k≤100000,1≤x,y≤n,1≤z≤10000。
*/

const int N = 310;
const int INF = 0x3f3f3f3f;
int n, m, k;
int d[N][N];


void floyd() {
	for (int k = 1; k <= n; k++) {
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				d[i][j] = min(d[i][k]+d[k][j],d[i][j]);
			}
		}
	}
}


int main()
{
	cin >> n >> m >> k;
	for (int i = 0; i <= n; i++) {
		for (int j = 0; j <= n; j++) {
			if (i == j) d[i][j] = 0;
			else d[i][j] = INF;
		}
	}
	for (int i = 0; i < m; i++) {
		int a, b, c; cin >> a >> b >> c;
		d[a][b] = min(d[a][b],c);
	}

	floyd();

	for (int i = 0; i < k; i++) {
		int a, b; cin >> a >> b;
		if (d[a][b] == 0x3f3f3f3f) { d[a][b] = -1; }
		cout << d[a][b] << endl;
	}

	return 0;
}

 